package com.yunti.springboot.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.zxing.WriterException;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.yunti.springboot.bo.UploadStuListAllBo;
import com.yunti.springboot.bo.UserBO;
import com.yunti.springboot.commonenum.ElectiveEnum;
import com.yunti.springboot.commonenum.SemesterEnum;
import com.yunti.springboot.commonenum.SexEnum;
import com.yunti.springboot.commonenum.SubjectEnum;
import com.yunti.springboot.config.component.AbstractCurrentRequestComponent;
import com.yunti.springboot.mapper.*;
import com.yunti.springboot.po.*;
import com.yunti.springboot.po.Class;
import com.yunti.springboot.service.StudentService;
import com.yunti.springboot.util.ExcelUtil;
import com.yunti.springboot.util.GradeYearUtil;
import com.yunti.springboot.util.ScoreWordUtil;
import com.yunti.springboot.util.SemesterUtil;
import com.yunti.springboot.vo.Result;
import com.yunti.springboot.vo.req.SearchStudentReq;
import com.yunti.springboot.vo.res.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@Slf4j
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Resource
    private AbstractCurrentRequestComponent abstractCurrentRequestComponent;

    @Resource
    private SchoolMapper schoolMapper;

    @Resource
    private ElectiveSubMapper electiveSubMapper;

    @Resource
    private SubjectMapper subjectMapper;

    @Resource
    private SubItemMapper subItemMapper;

    @Resource
    private ScoreMapper scoreMapper;

    @Resource
    private OptionMapper optionMapper;
    @Resource
    private ClassMapper classMapper;

    @Override
    public Result getStudentsInfo(SearchStudentReq searchStudentReq) {
        if (searchStudentReq.getCurrent() == null) {
            searchStudentReq.setCurrent(1);
        }
        if (searchStudentReq.getSize() == null) {
            searchStudentReq.setSize(10);
        }
        Page<Student> page = new Page<>(searchStudentReq.getCurrent(), searchStudentReq.getSize());
        LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>();
        UserBO userBO = abstractCurrentRequestComponent.getCurrentStaffId();
        System.out.println(userBO.getRank());
        if (userBO.getRank() != null && userBO.getRank().contains("getSchoolList")) {
            userBO.setSchoolId(searchStudentReq.getSchoolId());
            if (Objects.nonNull(searchStudentReq.getSchoolId())) {
                queryWrapper.eq(Student::getSchoolId, searchStudentReq.getSchoolId());
            }
        } else {
            queryWrapper.eq(Student::getSchoolId, userBO.getSchoolId());
        }

        if (Objects.nonNull(searchStudentReq.getId())) {
            queryWrapper.eq(Student::getId, searchStudentReq.getId());
        }

        if (Objects.nonNull(searchStudentReq.getName()) && !Objects.equals(searchStudentReq.getName(), "")) {
            queryWrapper.like(Student::getName, searchStudentReq.getName());
        }
        if (Objects.nonNull(searchStudentReq.getStuNo())) {
            queryWrapper.eq(Student::getStuNo, searchStudentReq.getStuNo());
        }

        if(Objects.nonNull(searchStudentReq.getNameOrStuNo())){
            queryWrapper.and(queryWrapper2 -> queryWrapper2.like(Student::getName, searchStudentReq.getNameOrStuNo()).or().eq(Student::getStuNo, searchStudentReq.getNameOrStuNo()));
        }
        if (Objects.nonNull(searchStudentReq.getClassId())) {
            queryWrapper.eq(Student::getClassId, searchStudentReq.getClassId());
        }
        if (Objects.nonNull(searchStudentReq.getSex())) {
            queryWrapper.eq(Student::getSex, searchStudentReq.getSex());
        }
        if (Objects.nonNull(searchStudentReq.getYear())) {
            queryWrapper.eq(Student::getYear, GradeYearUtil.getGradeYearByYear(searchStudentReq.getYear()));
        }
        Page<Student> students = this.page(page, queryWrapper);
        List<Student> records = students.getRecords();
        for (Student record : records) {
            Class aClass = classMapper.selectById(record.getClassId());
            if(aClass != null){
                record.setClassName(aClass.getClassName());
            }
        }
        return Result.success(students);
    }

    @Override
    public Result saveOrupdateStuInfo(Student studentInfo) {
        Student student = new Student();
        BeanUtils.copyProperties(studentInfo, student);
        if (student.getYear() != null) {
            student.setYear(GradeYearUtil.getGradeYearByYear(student.getYear()));
        }
        if (student.getSchoolId() == null) {
            student.setSchoolId(abstractCurrentRequestComponent.getCurrentStaffId().getSchoolId());
        }
        if (saveOrUpdate(student)) {
            return Result.success("添加成功");
        }
        return Result.success("添加失败");
    }

    @Override
    public Result getStudentsExamInfo(SearchStudentReq searchStudentReq) {
        Result result = getStudentsInfo(searchStudentReq);

        return result;
    }

    @Override
    public Result getStudentExamInfoById(SearchStudentReq searchStudentReq) {
        LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>();
        UserBO userBO = abstractCurrentRequestComponent.getCurrentStaffId();
        queryWrapper.eq(Student::getId, searchStudentReq.getId());
        queryWrapper.eq(Student::getSchoolId, userBO.getSchoolId());
        Student student = baseMapper.selectOne(queryWrapper);

        if (student == null) {
            return Result.error("没有人员");
        }

        StudentExamInfoRes studentExamInfoRes = new StudentExamInfoRes();
        studentExamInfoRes.setStudent(student);

        //如果查询学期为null,则表明查询当前学期
        if (searchStudentReq.getSemester() == null) {
            searchStudentReq.setSemester(SemesterUtil.getNowSemesterByStuYear(student.getYear()));
        }

        //获取每学期的考试科目
        LambdaQueryWrapper<ElectiveSub> electiveSubLambdaQueryWrapper = new LambdaQueryWrapper<>();
        electiveSubLambdaQueryWrapper.eq(ElectiveSub::getSemester, searchStudentReq.getSemester());
        List<ElectiveSub> electiveSubList = electiveSubMapper.selectList(electiveSubLambdaQueryWrapper);
        List<Integer> electiveSubIdList = electiveSubList.stream().map(ElectiveSub::getId).collect(Collectors.toList());
        if(electiveSubIdList.size() == 0){
            return Result.success(studentExamInfoRes);
        }

        //获取分数
        LambdaQueryWrapper<Score> scoreLambdaQueryWrapper = new LambdaQueryWrapper<Score>();
        scoreLambdaQueryWrapper.eq(Score::getStuId, student.getId());
        scoreLambdaQueryWrapper.in(Score::getElectiveId, electiveSubIdList);
        List<Score> scoreList = scoreMapper.selectList(scoreLambdaQueryWrapper);

        //获取选科科目
        LambdaQueryWrapper<Option> optionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        optionLambdaQueryWrapper.eq(Option::getStuId, student.getId());
        List<Option> optionList = optionMapper.selectList(optionLambdaQueryWrapper);
        Map<Integer, Option> optionMap = optionList.stream().collect(Collectors.toMap(Option::getElectiveSubId, Function.identity(), (k1, k2) -> k1));


        List<Integer> selectSubList = optionList.stream().map(Option::getSubId).distinct().collect(Collectors.toList());


        //通过科目id获取详情
        List<Integer> subIdList = electiveSubList.stream().map(ElectiveSub::getSubId).collect(Collectors.toList());
        subIdList.addAll(selectSubList);
        LambdaQueryWrapper<Subject> subjectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        subjectLambdaQueryWrapper.in(Subject::getId, subIdList);
        List<Subject> subjectList = subjectMapper.selectList(subjectLambdaQueryWrapper);
        Map<Integer, Subject> subjectMap = subjectList.stream().collect(Collectors.toMap(Subject::getId, Function.identity(), (k1, k2) -> k1));


        //通过科目id获取子项目
        LambdaQueryWrapper<SubItem> subItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
        subItemLambdaQueryWrapper.in(SubItem::getSubId, subIdList);
        List<SubItem> subItemList = subItemMapper.selectList(subItemLambdaQueryWrapper);
        Map<Integer, List<SubItem>> subItemListMap = subItemList.stream().collect(Collectors.groupingBy(SubItem::getSubId));


        List<StudentExamInfoRes.ElectiveSubRes> electiveSubResList = new ArrayList<>();
        for (int i = 0; i < electiveSubList.size(); i++) {
            StudentExamInfoRes.ElectiveSubRes electiveSubRes = new StudentExamInfoRes.ElectiveSubRes();
            BeanUtils.copyProperties(electiveSubList.get(i), electiveSubRes);

            if (electiveSubRes.getSubId() == -1) {
                if (optionMap.get(electiveSubRes.getId()) != null) {
                    electiveSubRes.setSubId(optionMap.get(electiveSubRes.getId()).getSubId());
                }
            }
            if (electiveSubRes.getSubId() != -1 && subjectMap.get(electiveSubRes.getSubId()) != null) {
                //设置科目名
                electiveSubRes.setSubName(subjectMap.get(electiveSubRes.getSubId()).getName());
                //获取子项目,并过滤性别
                List<SubItem> childSubItemList = subItemListMap.get(electiveSubRes.getSubId()).stream().filter(e -> !e.getItemNo().equals(0) && (e.getSextype().equals(0) || e.getSextype().equals(student.getSex()))).collect(Collectors.toList());
                List<SubItemRes> subItemResList = new ArrayList<>();
                for (int j = 0; j < childSubItemList.size(); j++) {
                    SubItemRes subItemRes = new SubItemRes();
                    BeanUtils.copyProperties(childSubItemList.get(j), subItemRes);

                    int finalJ = j;
                    List<Score> childScoreList = scoreList.stream().filter(new Predicate<Score>() {
                        @Override
                        public boolean test(Score score) {
                            return !score.getItemNo().equals(0) && score.getItemNo().equals(childSubItemList.get(finalJ).getItemNo()) && score.getElectiveId().equals(electiveSubRes.getId());
                        }
                    }).collect(Collectors.toList());

                    subItemRes.setScoreList(childScoreList);
                    subItemResList.add(subItemRes);
                }

                SubItemRes topSubItemRes = new SubItemRes();
                List<SubItem> topSubItemList = subItemListMap.get(electiveSubRes.getSubId()).stream().filter(e -> e.getItemNo().equals(0) && (e.getSextype().equals(0) || e.getSextype().equals(student.getSex()))).collect(Collectors.toList());
                if (topSubItemList.size() > 0) {
                    BeanUtils.copyProperties(topSubItemList.get(0), topSubItemRes);
                }

                topSubItemRes.setScoreList(scoreList.stream().filter(new Predicate<Score>() {
                    @Override
                    public boolean test(Score score) {
                        return score.getItemNo().equals(0) && score.getElectiveId().equals(electiveSubRes.getId());
                    }
                }).collect(Collectors.toList()));
                electiveSubRes.setTopSubItemRes(topSubItemRes);
                electiveSubRes.setSubItemList(subItemResList);
            }

            electiveSubResList.add(electiveSubRes);
        }

        studentExamInfoRes.setElectiveSubList(electiveSubResList);

        return Result.success(studentExamInfoRes);
    }

    @Override
    public void printStuExamInfoById(SearchStudentReq req, HttpServletResponse response) {
        List<StuExamAndScoreInfoRes> scoreInfoResArrayList = new ArrayList<>();
        //通过年导出两个学期
        if(req.getYear() != null){
            List<Integer>codes = SemesterEnum.getEnumByCode(req.getYear());
            //通过年获取学期数据
            for (Integer code : codes) {
                Result<StuExamAndScoreInfoRes> result = getStuExamInfoByStuIdAndSemester(req.getId(), code);
                scoreInfoResArrayList.add(result.getData());
            }
        }else {
            //通过学期导出
            Result<StuExamAndScoreInfoRes> result = getStuExamInfoByStuIdAndSemester(req.getId(), req.getSemester());
            scoreInfoResArrayList.add(result.getData());
        }


        try {
            // 设置输出的格式
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("fileName","utf-8"));
            Document doc = ScoreWordUtil.buildPrintScoreByList(scoreInfoResArrayList);
            doc.saveToStream(response.getOutputStream(), FileFormat.Docx);
        } catch (IOException | WriterException e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result importStuList(MultipartFile file) {
        Integer updateCount=0;
        Integer insertCount=0;
        UserBO userBO = abstractCurrentRequestComponent.getCurrentStaffId();
        String fileName = file.getOriginalFilename();
        assert fileName != null;
        String extension = fileName.substring(fileName.lastIndexOf(StrUtil.DOT) + 1);
        if (!extension.contains(ExcelUtil.EXCEL_EXTENSION)) {
            return Result.error("文件格式只能为[xls、xlsx]，上传的格式为：" + extension);
        }
        List<UploadStuListAllBo> bos = ExcelUtil.importExcel(file, UploadStuListAllBo.class, 0);
        if (CollUtil.isEmpty(bos)) {
            return Result.error("数据不能为空");
        }
        //遍历
        for (UploadStuListAllBo bo : bos) {
            if(bo.getStuNo()==null){
                continue;
            }

            //班级
            LambdaQueryWrapper<Class> classLambdaQueryWrapper = new LambdaQueryWrapper();
            classLambdaQueryWrapper.eq(Class::getClassName, bo.getClassName());
            classLambdaQueryWrapper.eq(Class::getGrade, bo.getYear());
            classLambdaQueryWrapper.eq(Class::getSchoolId, userBO.getSchoolId());
            List<Class>classList = classMapper.selectList(classLambdaQueryWrapper);
            Class cla = new Class();
            //班级不存在
            if (classList.isEmpty()){
                cla.setClassName(bo.getClassName());
                cla.setSchoolId(userBO.getSchoolId());
                cla.setGrade(bo.getYear());
                cla.setCreateTime(LocalDateTime.now());
                classMapper.insert(cla);
            }else {
                cla = classList.get(0);
            }
            //学生设置基本信息
            Student student = new Student();
            student.setSex(SexEnum.getCode(bo.getSex()));
            student.setSchoolId(userBO.getSchoolId());
            student.setClassId(cla.getId());
            BeanUtils.copyProperties(bo, student);
            LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(Student::getStuNo, student.getStuNo());
            queryWrapper.eq(Student::getYear, bo.getYear());
            queryWrapper.eq(Student::getSchoolId, student.getSchoolId());
            //如果已有考生信息就更新
            if (baseMapper.exists(queryWrapper)) {
                baseMapper.update(student,queryWrapper);
                updateCount++;
            } else {
                insertCount++;
                baseMapper.insert(student);
            }
        }
        return Result.success(updateCount+"条更新成功,"+insertCount+"条插入成功",null);
    }

    @Override
    public Result getStuExamInfoById(SearchStudentReq req) {
        StuExamAndScoreInfoRes stuExamInfoRes = new StuExamAndScoreInfoRes();
        Student student = this.baseMapper.selectById(req.getId());
        Class clas = classMapper.selectById(student.getClassId());
        if (clas != null){
            student.setClassName(clas.getClassName());
        }else {
            student.setClassName("");
        }
        stuExamInfoRes.setStudent(student);
//        获取学科
        LambdaQueryWrapper<ElectiveSub> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(ElectiveSub::getSemester, req.getSemester());
        lambdaQueryWrapper.and(e ->e.eq(ElectiveSub::getSex, student.getSex()).or().eq(ElectiveSub::getSex, SexEnum.通用.getCode()));
        List<ElectiveSub> allElectiveSub = electiveSubMapper.selectList(lambdaQueryWrapper);

        //获取学科
        StuExamInfo stuExamInfo = new StuExamInfo();
        List<StuExamInfo.StuExam> stuExamList = new ArrayList<>();
        stuExamInfo.setStuExamList(stuExamList);

        //获取系统全部科目（大项）
        List<Subject> subjects = subjectMapper.selectAll();
        Map<Integer, Subject> subMap = subjects.stream().collect(Collectors.toMap(Subject::getId, Function.identity()));
        //获取系统全部科目（小项）
        List<SubItem> subItems = subItemMapper.selectAll();
        Map<Integer, List<SubItem>> subItemMap = subItems.stream().collect(Collectors.groupingBy(SubItem::getSubId));
        for (int i = 1; i <= 4; i++) {
            //获取考生各个类型考试科目吗
            int finalI = i;
            List<ElectiveSub> electiveSubList = allElectiveSub.stream().filter(a -> a.getType() == finalI).collect(Collectors.toList());
            if (electiveSubList.isEmpty()) {
                continue;
            }
            //如果为1必考科目
            if (i == 1 || i == 2 || i == 4) {
                StuExamInfo.StuExam stuExam = new StuExamInfo.StuExam();
                if (i == 1) {
                    stuExam.setTittle("基本素质");
                }
                if (i == 2) {
                    stuExam.setTittle("选考科目");
                }
                if (i == 4) {
                    stuExam.setTittle("体制健康");
                }
                List<StuExamInfo.StuExamDetail> stuExamDetails = new ArrayList<>();
                //遍历选课配置
                for (ElectiveSub sub : electiveSubList) {
                    StuExamInfo.StuExamDetail stuExamDetail = new StuExamInfo.StuExamDetail();
                    //-1表示选修
                    if (sub.getSubId() <= 0) {
                        LambdaQueryWrapper<Option>lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper1.eq(Option::getStuId,student.getId());
                        lambdaQueryWrapper1.eq(Option::getElectiveSubId,sub.getId());
                        List<Option>list = optionMapper.selectList(lambdaQueryWrapper1);
                        if(list.size()== 0){
                            stuExamDetail.setTittle("未选");
                        }else {
                            Option option = list.get(0);
                            stuExamDetail.setTittle(subMap.get(option.getSubId()).getName());
                            stuExamDetail.setKey(Objects.requireNonNull(SubjectEnum.getEnumBySubId(subMap.get(option.getSubId()).getId())).getKey());
                        }
                    }else{
                        stuExamDetail.setTittle(subMap.get(sub.getSubId()).getName());
                        stuExamDetail.setKey(Objects.requireNonNull(SubjectEnum.getEnumBySubId(subMap.get(sub.getSubId()).getId())).getKey());
                    }
                    stuExamDetails.add(stuExamDetail);
                }
                stuExam.setStuExamDetails(stuExamDetails);
                stuExamList.add(stuExam);
            }
            //表示八选二（多个小项）
            if (i == 3) {
                for (ElectiveSub sub : electiveSubList) {
                    StuExamInfo.StuExam stuExam = new StuExamInfo.StuExam();
                    stuExam.setType(i);
                    LambdaQueryWrapper<Option>lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper1.eq(Option::getStuId,student.getId());
                    lambdaQueryWrapper1.eq(Option::getElectiveSubId,sub.getId());
                    List<Option>list = optionMapper.selectList(lambdaQueryWrapper1);
                    if(list.size()== 0){
                        stuExam.setTittle("未选");
                    }else {
                        log.info("cs{}",sub);
                        Option option = list.get(0);
                        stuExam.setTittle(subMap.get(option.getSubId()).getName());
                        List<SubItem> subItemList = subItemMap.get(option.getSubId());
                        List<StuExamInfo.StuExamDetail> stuExamDetails = new ArrayList<>();
                        for (SubItem subItem : subItemList) {
                            StuExamInfo.StuExamDetail stuExamDetail = new StuExamInfo.StuExamDetail();
                            stuExamDetail.setTittle(subItem.getName());
                            stuExamDetail.setKey(Objects.requireNonNull(SubjectEnum.getEnumBySubId(subMap.get(option.getSubId()).getId())).getKey() + subItem.getItemNo());
                            stuExamDetails.add(stuExamDetail);
                        }
                        stuExam.setStuExamDetails(stuExamDetails);
                    }

                    stuExamList.add(stuExam);
                }
            }
        }
        stuExamInfoRes.setStuExamInfo(stuExamInfo);
        StuScoreInfo stuScoreInfo = new StuScoreInfo();
        List<Map<String,String>> stuScoreList = new ArrayList<>();
        //生成三行
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                HashMap<String, String> stuScoreMap = new HashMap<>();
                if (j == 1) {
                    stuScoreMap.put("tittle", StrUtil.format("第{}次成绩", i));
                }
                if (j == 2) {
                    stuScoreMap.put("tittle", "得分");
                }
                if (j == 3) {
                    stuScoreMap.put("tittle", "考官");
                }
                stuScoreMap.put("liubao", " ");
                stuScoreList.add(stuScoreMap);
            }
        }

        //通过选科和学生获取成绩
        List<Integer>  integers= allElectiveSub.stream().map(ElectiveSub::getId).collect(Collectors.toList());
        if(integers.size() != 0){
            LambdaQueryWrapper<Score>queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Score::getStuId,student.getId());
            queryWrapper.in(Score::getElectiveId,integers);
            List<Score> scoreList = scoreMapper.selectList(queryWrapper);
            for (Score score : scoreList) {
                if(score.getCount() != null){
                    if (score.getCount() == 1) {
                        Map<String,String> stuScoreMap = stuScoreList.get(0);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), score.getRawScore());

                        stuScoreMap = stuScoreList.get(1);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), String.valueOf(score.getConversionScore()));

                    }
                    if (score.getCount() == 2) {
                        Map<String,String> stuScoreMap = stuScoreList.get(3);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), score.getRawScore());

                        stuScoreMap = stuScoreList.get(4);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), String.valueOf(score.getConversionScore()));
                    }

                    if (score.getCount() == 3) {
                        Map<String,String> stuScoreMap = stuScoreList.get(6);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), score.getRawScore());
                        stuScoreMap = stuScoreList.get(7);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(),String.valueOf(score.getConversionScore()));
                    }
                }

            }
        }
        stuScoreInfo.setStuScoreList(stuScoreList);
        stuExamInfoRes.setStuScoreInfo(stuScoreInfo);
        return Result.success(stuExamInfoRes);
    }

    @Override
    public Result getAllSubById(SearchStudentReq searchStudentReq) {
        //获取每学期的考试科目
        LambdaQueryWrapper<ElectiveSub> electiveSubLambdaQueryWrapper = new LambdaQueryWrapper<>();
        electiveSubLambdaQueryWrapper.eq(ElectiveSub::getSemester, searchStudentReq.getSemester());
        electiveSubLambdaQueryWrapper.orderByAsc(ElectiveSub::getType);
        List<ElectiveSub> electiveSubList = electiveSubMapper.selectList(electiveSubLambdaQueryWrapper);
        //获取系统全部科目（大项）
        List<Subject> subjects = subjectMapper.selectAll();
        Map<Integer, Subject> subMap = subjects.stream().collect(Collectors.toMap(Subject::getId, Function.identity()));
        List<StudentSubRes>resList = new ArrayList<>();
        for (ElectiveSub sub : electiveSubList) {
            StudentSubRes res = new StudentSubRes();
            res.setType(sub.getType());
            res.setElectiveSubId(sub.getId());
            res.setTypeName(ElectiveEnum.getValue(sub.getType()));
            if (sub.getSubId() <= 0) {
                LambdaQueryWrapper<Option>lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                lambdaQueryWrapper1.eq(Option::getStuId,searchStudentReq.getId());
                lambdaQueryWrapper1.eq(Option::getElectiveSubId,sub.getId());
                List<Option>list = optionMapper.selectList(lambdaQueryWrapper1);
                if(list.size()== 0){
                    res.setSubName("未选");
                }else {
                    Option option = list.get(0);
                    res.setOptionId(option.getId());
                    res.setSubName(subMap.get(option.getSubId()).getName());
                }
            }else{
                System.out.println(sub.getSubId());
                res.setSubName(subMap.get(sub.getSubId()).getName());
            }
            resList.add(res);
        }

        return Result.success(resList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result adminImportStuList(MultipartFile file, Integer schoolId) {
        Integer updateCount=0;
        Integer insertCount=0;
        String fileName = file.getOriginalFilename();
        assert fileName != null;
        String extension = fileName.substring(fileName.lastIndexOf(StrUtil.DOT) + 1);
        if (!extension.contains(ExcelUtil.EXCEL_EXTENSION)) {
            return Result.error("文件格式只能为[xls、xlsx]，上传的格式为：" + extension);
        }
        List<UploadStuListAllBo> bos = ExcelUtil.importExcel(file, UploadStuListAllBo.class, 0);
        if (CollUtil.isEmpty(bos)) {
            return Result.error("数据不能为空");
        }
        //遍历
        for (UploadStuListAllBo bo : bos) {
            if(bo.getStuNo()==null){
                continue;
            }

            //班级
            LambdaQueryWrapper<Class> classLambdaQueryWrapper = new LambdaQueryWrapper();
            classLambdaQueryWrapper.eq(Class::getClassName, bo.getClassName());
            classLambdaQueryWrapper.eq(Class::getGrade, bo.getYear());
            classLambdaQueryWrapper.eq(Class::getSchoolId, schoolId);
            List<Class>classList = classMapper.selectList(classLambdaQueryWrapper);
            Class cla = new Class();
            //班级不存在
            if (classList.isEmpty()){
                cla.setClassName(bo.getClassName());
                cla.setSchoolId(schoolId);
                cla.setGrade(bo.getYear());
                cla.setCreateTime(LocalDateTime.now());
                classMapper.insert(cla);
            }else {
                cla = classList.get(0);
            }
            //学生设置基本信息
            Student student = new Student();
            student.setSex(SexEnum.getCode(bo.getSex()));
            student.setSchoolId(schoolId);
            student.setClassId(cla.getId());
            BeanUtils.copyProperties(bo, student);
            LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(Student::getStuNo, student.getStuNo());
            queryWrapper.eq(Student::getYear, bo.getYear());
            queryWrapper.eq(Student::getSchoolId, student.getSchoolId());
            //如果已有考生信息就更新
            if (baseMapper.exists(queryWrapper)) {
                baseMapper.update(student,queryWrapper);
                updateCount++;
            } else {
                insertCount++;
                baseMapper.insert(student);
            }
        }
        return Result.success(updateCount+"条更新成功,"+insertCount+"条插入成功",null);
    }
    private Result<StuExamAndScoreInfoRes> getStuExamInfoByStuIdAndSemester(Integer stuId, Integer semester) {
        StuExamAndScoreInfoRes stuExamInfoRes = new StuExamAndScoreInfoRes();
        stuExamInfoRes.setSemesterEnum(SemesterEnum.getEnumBySemester(semester));
        //获取学生
        Student student = this.baseMapper.selectById(stuId);
        Class clas = classMapper.selectById(student.getClassId());
        if (clas != null){
            student.setClassName(clas.getClassName());
        }else {
            student.setClassName("");
        }
        //获取学校
        School school = schoolMapper.selectById(student.getSchoolId());
        stuExamInfoRes.setStudent(student);
        stuExamInfoRes.setSchool(school);
        //通过学期获取学科
        LambdaQueryWrapper<ElectiveSub> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(ElectiveSub::getSemester, semester);
        lambdaQueryWrapper.and(e ->e.eq(ElectiveSub::getSex, student.getSex()).or().eq(ElectiveSub::getSex, SexEnum.通用.getCode()));
        List<ElectiveSub> allElectiveSub = electiveSubMapper.selectList(lambdaQueryWrapper);
        //获取学科
        StuExamInfo stuExamInfo = new StuExamInfo();
        List<StuExamInfo.StuExam> stuExamList = new ArrayList<>();
        stuExamInfo.setStuExamList(stuExamList);

        //获取系统全部科目（大项）
        List<Subject> subjects = subjectMapper.selectAll();
        Map<Integer, Subject> subMap = subjects.stream().collect(Collectors.toMap(Subject::getId, Function.identity()));
        //获取系统全部科目（小项）
        List<SubItem> subItems = subItemMapper.selectAll();
        Map<Integer, List<SubItem>> subItemMap = subItems.stream().collect(Collectors.groupingBy(SubItem::getSubId));

        //通过类型遍历
        for (int i = 1; i <= 4; i++) {
            //获取考生各个类型科
            int finalI = i;
            List<ElectiveSub> electiveSubList = allElectiveSub.stream().filter(a -> a.getType() == finalI).collect(Collectors.toList());
            if (electiveSubList.isEmpty()) {
                continue;
            }
            //如果为1必考科目
            if (i == 1 || i == 2 || i == 4) {
                StuExamInfo.StuExam stuExam = new StuExamInfo.StuExam();
                stuExam.setType(i);
                if (i == 1) {
                    stuExam.setTittle("基础体能必考");
                }
                if (i == 2) {
                    stuExam.setTittle("基础体能选考");
                }
                if (i == 4) {
                    stuExam.setTittle("体质健康监测");
                }
                List<StuExamInfo.StuExamDetail> stuExamDetails = new ArrayList<>();
                //遍历选课配置
                for (ElectiveSub sub : electiveSubList) {
                    StuExamInfo.StuExamDetail stuExamDetail = new StuExamInfo.StuExamDetail();
                    //-1表示选修
                    if (sub.getSubId() <= 0) {
                        LambdaQueryWrapper<Option>lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper1.eq(Option::getStuId,student.getId());
                        lambdaQueryWrapper1.eq(Option::getElectiveSubId,sub.getId());
                         List<Option>list = optionMapper.selectList(lambdaQueryWrapper1);
                         if(list.size()== 0){
                             stuExamDetail.setTittle("未选");
                         }else {
                             Option option = list.get(0);
                             stuExamDetail.setTittle(subMap.get(option.getSubId()).getName());
                             stuExamDetail.setKey(Objects.requireNonNull(SubjectEnum.getEnumBySubId(subMap.get(option.getSubId()).getId())).getKey());
                         }
                    }else{
                        stuExamDetail.setTittle(subMap.get(sub.getSubId()).getName());
                        stuExamDetail.setKey(SubjectEnum.getEnumBySubId(subMap.get(sub.getSubId()).getId()).getKey());
                    }
                    stuExamDetails.add(stuExamDetail);
                }
                stuExam.setStuExamDetails(stuExamDetails);
                stuExamList.add(stuExam);
            }
            //表示八选二（多个小项）
            if (i == 3) {
                for (ElectiveSub sub : electiveSubList) {
                    StuExamInfo.StuExam stuExam = new StuExamInfo.StuExam();
                    stuExam.setType(i);
                        LambdaQueryWrapper<Option>lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper1.eq(Option::getStuId,student.getId());
                        lambdaQueryWrapper1.eq(Option::getElectiveSubId,sub.getId());
                        List<Option>list = optionMapper.selectList(lambdaQueryWrapper1);
                        if(list.size()== 0){
                            stuExam.setTittle("未选");
                        }else {
                            log.info("cs{}",sub);
                            Option option = list.get(0);
                            stuExam.setTittle(subMap.get(option.getSubId()).getName());
                            List<SubItem> subItemList = subItemMap.get(option.getSubId());
                            List<StuExamInfo.StuExamDetail> stuExamDetails = new ArrayList<>();
                            for (SubItem subItem : subItemList) {
                                StuExamInfo.StuExamDetail stuExamDetail = new StuExamInfo.StuExamDetail();
                                stuExamDetail.setTittle(subItem.getName());
                                stuExamDetail.setKey(Objects.requireNonNull(SubjectEnum.getEnumBySubId(subMap.get(option.getSubId()).getId())).getKey() + subItem.getItemNo());
                                stuExamDetails.add(stuExamDetail);
                            }
                            stuExam.setStuExamDetails(stuExamDetails);
                        }

                    stuExamList.add(stuExam);
                }
            }
        }
        stuExamInfoRes.setStuExamInfo(stuExamInfo);
        StuScoreInfo stuScoreInfo = new StuScoreInfo();
        List<Map<String,String>> stuScoreList = new ArrayList<>();
        //生成三行
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                HashMap<String, String> stuScoreMap = new HashMap<>();
                if (j == 1) {
                    stuScoreMap.put("tittle", StrUtil.format("第{}次成绩", i));
                }
                if (j == 2) {
                    stuScoreMap.put("tittle", "得分");
                }
                if (j == 3) {
                    stuScoreMap.put("tittle", "考官");
                }
                stuScoreMap.put("liubao", " ");
                stuScoreList.add(stuScoreMap);
            }
        }

        //通过选科和学生获取成绩
        List<Integer>  integers= allElectiveSub.stream().map(ElectiveSub::getId).collect(Collectors.toList());
        if(integers.size() != 0){
            LambdaQueryWrapper<Score>queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Score::getStuId,student.getId());
            queryWrapper.in(Score::getElectiveId,integers);
            List<Score> scoreList = scoreMapper.selectList(queryWrapper);
            for (Score score : scoreList) {
                if(score.getCount() != null){
                    if (score.getCount() == 1) {
                        Map<String,String> stuScoreMap = stuScoreList.get(0);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), score.getRawScore());

                        stuScoreMap = stuScoreList.get(1);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), String.valueOf(score.getConversionScore()));

                    }
                    if (score.getCount() == 2) {
                        Map<String,String> stuScoreMap = stuScoreList.get(3);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), score.getRawScore());

                        stuScoreMap = stuScoreList.get(4);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), String.valueOf(score.getConversionScore()));
                    }

                    if (score.getCount() == 3) {
                        Map<String,String> stuScoreMap = stuScoreList.get(6);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(), score.getRawScore());
                        stuScoreMap = stuScoreList.get(7);
                        stuScoreMap.put(Objects.requireNonNull(SubjectEnum.getEnumBySubId(score.getSubId())).getKey(),String.valueOf(score.getConversionScore()));
                    }
                }

            }
        }
        stuScoreInfo.setStuScoreList(stuScoreList);
        stuExamInfoRes.setStuScoreInfo(stuScoreInfo);
        return Result.success(stuExamInfoRes);


    }
}
